/*
 * This file is part of ddesktop: remote desktop system for iPad 
 *
 * Copyright (C) 2010 Kazuhiro Satoh
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. if not, see <http://www.gnu.org/licenses/>.
 */

#import "RemoteViewContainerController.h"
#import "SettingViewController.h"

@interface RemoteViewContainerController ()
- (void)setSubviewLocation;
@end


@implementation RemoteViewContainerController


- (void)dealloc {
	[self stopSessionAndUnconnect];
	[_remoteViewController release];
	[_updateViewTimer release];
    [super dealloc];
}


- (id)initWithAppStateManagerDelegate:(id)delegate setting:(Setting*)setting;
{
	if ((self = [super init])) {
		_setting = setting;
		_appStateManagerDelegate = delegate;
		_ddclientPort = nil;
		
		[[_setting itemForKeyPath:@"Global.WheelSpeed"  ] addObserver:self action:@selector(settingItemWheelSpeedIsChanged:)];
		[[_setting itemForKeyPath:@"Global.ImageQuality"] addObserver:self action:@selector(settingItemImageQualityIsChanged:)];
	}
	return self;
}


// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
	[super loadView];
	self.view.backgroundColor = [UIColor viewFlipsideBackgroundColor];
	_activePopover = nil;
	_shortcutViewIsHidden = true;
	_fullscreen = false;
	_updateViewTimer = nil;
	
	{	// _remoteViewController
		_remoteViewController = [[RemoteViewController alloc] init];
		_remoteViewController.view.frame = [UIScreen mainScreen].bounds;
		[self.view addSubview:_remoteViewController.view];
	}
	
	{ // _shortcutView
		_shortcutView = [[ShortcutView alloc] init];
		_shortcutView.delegate = self;
		[self.view addSubview:_shortcutView];
		[_shortcutView release];
	}
	
	{ // _keyboardView
		_keyboardView = [[KeyboardView alloc] init];
		_keyboardView.delegate = self;
		[self.view addSubview:_keyboardView];
		[_keyboardView release];
	}
	
	{ // init tool bar
		_toolbar = [UIToolbar new];
		_toolbar.barStyle = UIBarStyleBlack;
		//_toolbar.tintColor = UIColor.blackColor;
		//NSLog(@"tintColor=%d", _toolbar.tintColor);
		_toolbar.translucent = YES;
		[_toolbar sizeToFit];

		_buttonShortcut = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"icon_shortcut.png"]
														   style:UIBarButtonItemStylePlain
														  target:self
														  action:@selector(toolbarButtonAction:)];
		_buttonKeyboard = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"icon_keyboard.png"]
														   style:UIBarButtonItemStylePlain
														  target:self
														  action:@selector(toolbarButtonAction:)];
		_buttonSetting = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"icon_manage.png"]
														  style:UIBarButtonItemStylePlain
														 target:self
														 action:@selector(toolbarButtonAction:)];
		_buttonHideToolbar = [[UIBarButtonItem alloc] initWithTitle:@">"
														   style:UIBarButtonItemStyleBordered
														  target:self
														  action:@selector(toolbarButtonAction:)];
		UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
																				   target:nil
																				   action:nil];
		NSArray *elements = [NSArray arrayWithObjects:
							 flexSpace,
							 _buttonShortcut,
							 _buttonKeyboard,
							 _buttonSetting,
							 _buttonHideToolbar,
							 nil];
		[_buttonShortcut release];
		[_buttonKeyboard release];
		[_buttonSetting release];
		[_buttonHideToolbar release];
		[flexSpace release];
		
		[_toolbar setItems:elements animated:NO];
		
		[self.view addSubview:_toolbar];
		[_toolbar release];
	}
	
	{ // mouse button selector
		NSArray *elements = [NSArray arrayWithObjects:@"Left", @"Middle", @"Right", @"None", nil];
		_mouseActionSelector = [[UISegmentedControl alloc]initWithItems:elements];
		_mouseActionSelector.segmentedControlStyle = UISegmentedControlStyleBar;
		_mouseActionSelector.tintColor = UIColor.darkGrayColor;
		[_mouseActionSelector addTarget:self
								 action:@selector(mouseActionSelectionChanged:)
					   forControlEvents:UIControlEventValueChanged];
		_mouseActionSelector.selectedSegmentIndex = _remoteViewController.mouseAction;
		[_toolbar addSubview:_mouseActionSelector];
		[_mouseActionSelector release];
	}

	{ // window op selector
		NSArray *elements = [NSArray arrayWithObjects:@"Move", @"Resize", nil];
		_windowActionSelector = [[UISegmentedControl alloc]initWithItems:elements];
		_windowActionSelector.segmentedControlStyle = UISegmentedControlStyleBar;
		_windowActionSelector.tintColor = UIColor.darkGrayColor;
		[_windowActionSelector addTarget:self
								 action:@selector(windowActionSelectionChanged:)
					   forControlEvents:UIControlEventValueChanged];
		_windowActionSelector.selectedSegmentIndex = _remoteViewController.windowAction;
		[_toolbar addSubview:_windowActionSelector];
		[_windowActionSelector release];
	}
	
	{ // mode selector
		NSArray *elements = [NSArray arrayWithObjects:@"Mouse", @"Wheel", @"Window", nil];
		_modeSelector = [[UISegmentedControl alloc]initWithItems:elements];
		_modeSelector.segmentedControlStyle = UISegmentedControlStyleBar;
		_modeSelector.tintColor = UIColor.darkGrayColor;
		[_modeSelector addTarget:self
						  action:@selector(modeChanged:)
				forControlEvents:UIControlEventValueChanged];
		_modeSelector.selectedSegmentIndex = _remoteViewController.mode;
		[_toolbar addSubview:_modeSelector];
		[_modeSelector release];
	}
	
	{ // show toolbar button
		_buttonShowToolbar = [[UIButton buttonWithType: UIButtonTypeRoundedRect] retain];
		[_buttonShowToolbar setTitle:@"<" forState:UIControlStateNormal];
		_buttonShowToolbar.frame = CGRectMake(0, 0, 32, 32);
		_buttonShowToolbar.alpha = 0.5;
		[_buttonShowToolbar addTarget:self action:@selector(toolbarButtonAction:) forControlEvents:UIControlEventTouchDown];
		[self.view addSubview:_buttonShowToolbar];

		const int margin = 4;
		_buttonShowToolbar.frame = CGRectMake(self.view.bounds.size.width - _buttonShowToolbar.frame.size.width - margin,
											  self.view.bounds.size.height - _buttonShowToolbar.frame.size.height - margin,
											  _buttonShowToolbar.frame.size.width,
											  _buttonShowToolbar.frame.size.height);
		_buttonShowToolbar.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin
											| UIViewAutoresizingFlexibleTopMargin;
	}

	[self setSubviewLocation];
}


- (bool)connectToHost:(NSString*) host port:(int)port
{
	[self stopSessionAndUnconnect];
	_ddclientPort = [[DDClientPort alloc] init];
	
	@try {
		[_ddclientPort connectToHost:host port:port];
	}
	@catch (NSException * e) {
		[self stopSessionAndUnconnect];
		UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[e name] message:[e reason] delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
		[alert show];
		[alert release];
		return false;
	}
	@finally {
		//
	}
	
	return true;
}


- (bool)startSession
{	
	if(![_remoteViewController startSessionWithPort:_ddclientPort]){
		[self stopSessionAndUnconnect];
		return false;
	}
	
	_remoteViewController.mouseWheelSensitivity = [(NSNumber*)[_setting itemForKeyPath:@"Global.WheelSpeed"].value intValue];
	[_ddclientPort changeImageQuality:[(NSNumber*)[_setting itemForKeyPath:@"Global.ImageQuality"].value doubleValue]];

	if (_updateViewTimer != nil) {
		[_updateViewTimer invalidate];
	}
	_updateViewTimer = [NSTimer scheduledTimerWithTimeInterval:1/20.0
														 target:self
													   selector:@selector(animate:)
													   userInfo:nil
														repeats:YES];
	
	return true;
}


- (bool)stopSessionAndUnconnect
{
	if(_ddclientPort != nil){
		[_remoteViewController stopSession];
		[_ddclientPort close];
		[_ddclientPort release];
		_ddclientPort = nil;
	}

	if(_updateViewTimer != nil){
		[_updateViewTimer invalidate];
		_updateViewTimer = nil;
	}
	
	return true;
}


- (void)didReceiveMemoryWarning {
	// Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
	
	// Release any cached data, images, etc that aren't in use.
}


- (void)viewWillAppear:(BOOL)animated
{
	[self setSubviewLocation];
	_remoteViewController.view.frame = self.view.bounds;
	[_remoteViewController.view setNeedsDisplay];
	[_remoteViewController updatePeepFrame];
	[_remoteViewController updateView];
}


// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return YES;
}


- (void)willRotateToInterfaceOrientation:
(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
	_toolbar.hidden = YES;
	_shortcutView.hidden = YES;
	_buttonShowToolbar.hidden = YES;
	if(_activePopover != nil){
		[_activePopover dismissPopoverAnimated:NO];
		_activePopover = nil;
	}
}

- (void)didRotateFromInterfaceOrientation:
(UIInterfaceOrientation)fromInterfaceOrientation {
	[self setSubviewLocation];

	_remoteViewController.view.frame = self.view.bounds;
	[_remoteViewController.view setNeedsDisplay];
	[_remoteViewController updatePeepFrame];
	[_remoteViewController updateView];
}


-(void)animate:(NSTimer*)timer
{
	if (_ddclientPort.state == PORT_STATE_OPENED){
		[_remoteViewController updateView];
	}
	
	if(_ddclientPort.state == PORT_STATE_ERROR){
		[self stopSessionAndUnconnect];

		UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Disconnected abnormally" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
		[alert show];
		[alert release];

		if(_activePopover != nil){
			[_activePopover dismissPopoverAnimated:NO];
			_activePopover = nil;
		}

		[_appStateManagerDelegate popCurrentState];
	}
}



-(void)mouseActionSelectionChanged:(id)sender
{
	UISegmentedControl* control = (UISegmentedControl*)sender;
	_remoteViewController.mouseAction = control.selectedSegmentIndex;
}	


-(void)windowActionSelectionChanged:(id)sender
{
	UISegmentedControl* control = (UISegmentedControl*)sender;
	_remoteViewController.windowAction = control.selectedSegmentIndex;
}


-(void)modeChanged:(id)sender
{
	UISegmentedControl* control = (UISegmentedControl*)sender;
	_remoteViewController.mode = control.selectedSegmentIndex;
	
	_mouseActionSelector.hidden = control.selectedSegmentIndex != RV_MOUSE_MODE;
	_windowActionSelector.hidden = control.selectedSegmentIndex != RV_WINDOW_MODE;
}


-(void)disconnectionButtonAction:(id)sender
{
	[self stopSessionAndUnconnect];
	if(_activePopover != nil){
		[_activePopover dismissPopoverAnimated:NO];
		_activePopover = nil;
	}
	[_appStateManagerDelegate popCurrentState];
}


-(void)toolbarButtonAction:(id)sender
{
	if(_activePopover != nil){
		[_activePopover dismissPopoverAnimated:NO];
		_activePopover = nil;
	}
	
	if(sender == _buttonShortcut){
		_shortcutViewIsHidden = !_shortcutViewIsHidden;
		[self setSubviewLocation];
	}
	else if(sender == _buttonKeyboard){
		[_keyboardView showKeyboard];
	}
	else if(sender == _buttonSetting){
		SettingViewController* settingView = [[[SettingViewController alloc] initWithSetting:_setting] autorelease];
		UINavigationController* naviController = [[[UINavigationController alloc] initWithRootViewController:settingView] autorelease];

		UIBarButtonItem* disconnectButton = [[[UIBarButtonItem alloc] initWithTitle:@"Disconnect"
																			  style:UIBarButtonItemStylePlain
																			 target:self
																			 action:@selector(disconnectionButtonAction:)] autorelease];
		settingView.navigationItem.leftBarButtonItem = disconnectButton;
		settingView.navigationItem.title = @"Settings";

		UIPopoverController* pop = [[UIPopoverController alloc] initWithContentViewController:naviController];
		[pop presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];
		_activePopover = pop;
	}
	else if(sender == _buttonHideToolbar){
		_fullscreen = true;
		[self setSubviewLocation];
	}
	else if(sender == _buttonShowToolbar){
		_fullscreen = false;
		[self setSubviewLocation];
	}
}


-(void)keyboardViewPushed:(char)asciiKeyCode
{
	int keycode;
	switch (asciiKeyCode) {
		case '\n': keycode = DD_KEY_RETURN; break;
		case '\b': keycode = DD_KEY_BACKSPACE; break;
		case ' ':  keycode = DD_KEY_SPACE; break;
		default:   keycode = asciiKeyCode; break;
	}
	
	[_ddclientPort sendUIEvent: DD_KEYBOARD_PUSH
					eventOwner: DD_KEYBOARD
						param1: keycode
						param2: 0];
}


-(void) keyboardViewKeyboardWasShown
{
	[self setSubviewLocation];
}


-(void) keyboardViewKeyboardWillHide
{
	[self setSubviewLocation];
}


- (void)shortcutKeyWasDown:(enum DDKeyCode)keyCode
{
	[_ddclientPort sendUIEvent: DD_KEYBOARD_DOWN
					eventOwner: DD_KEYBOARD
						param1: keyCode
						param2: 0];
}


- (void)shortcutKeyWasUp:(enum DDKeyCode)keyCode
{
	[_ddclientPort sendUIEvent: DD_KEYBOARD_UP
					eventOwner: DD_KEYBOARD
						param1: keyCode
						param2: 0];
}


-(void) settingItemWheelSpeedIsChanged:(NSObject*)value
{
	_remoteViewController.mouseWheelSensitivity = [(NSNumber*)value floatValue];
}


-(void) settingItemImageQualityIsChanged:(NSObject*)value
{
	[_ddclientPort changeImageQuality:[(NSNumber*)value intValue]];
}


- (void)setSubviewLocation
{
	if(_fullscreen){
		const int margin = 4;
		_buttonShowToolbar.frame = CGRectMake(self.view.bounds.size.width - _buttonShowToolbar.frame.size.width - margin,
											  self.view.bounds.size.height - _buttonShowToolbar.frame.size.height - margin,
											  _buttonShowToolbar.frame.size.width,
											  _buttonShowToolbar.frame.size.height);
	}
	else{
		_toolbar.frame = CGRectMake(0,
									self.view.bounds.size.height - _toolbar.frame.size.height,
									self.view.bounds.size.width,
									_toolbar.frame.size.height);
		_modeSelector.frame = CGRectMake((_toolbar.frame.size.width - _modeSelector.frame.size.width)/2,
										 (_toolbar.frame.size.height - _modeSelector.frame.size.height)/2,
										 _modeSelector.frame.size.width,
										 _modeSelector.frame.size.height);
		_mouseActionSelector.frame = CGRectMake(4,
												(_toolbar.frame.size.height - _mouseActionSelector.frame.size.height)/2,
												_mouseActionSelector.frame.size.width,
												_mouseActionSelector.frame.size.height);
		_windowActionSelector.frame = CGRectMake(4,
												 (_toolbar.frame.size.height - _windowActionSelector.frame.size.height)/2,
												 _windowActionSelector.frame.size.width,
												 _windowActionSelector.frame.size.height);		
		_shortcutView.frame = CGRectMake(4, 
										 MIN(_toolbar.frame.origin.y, self.view.bounds.size.height - _keyboardView.keyboardSize.height) - _shortcutView.frame.size.height,
										 _shortcutView.frame.size.width,
										 _shortcutView.frame.size.height);	
	}
	
	_toolbar.hidden = _fullscreen;
	_modeSelector.hidden = _fullscreen;
	_mouseActionSelector.hidden = _fullscreen || (_remoteViewController.mode != RV_MOUSE_MODE);
	_windowActionSelector.hidden = _fullscreen || (_remoteViewController.mode != RV_WINDOW_MODE);
	_shortcutView.hidden = (_shortcutViewIsHidden && _keyboardView.keyboardIsHidden) || _fullscreen;
	_buttonShowToolbar.hidden = !_fullscreen;
}

		   
@end
